package com.mac.bluetoothbt.feature;

import android.util.Log;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>设备实体</p>
 */
class DeviceEntity implements Serializable {
    static final int BUFFERLENGTH = 2000;
    /**
     * 一个Sensor长度
     */
    static final int SENSOR_LENGTH = 20;

    private static final int REGISTERS_OFFSET = 3;
    /**
     * 各个传感器的偏移
     */
    private static final int[] SENSORS_OFFSET = {
            REGISTERS_OFFSET + SENSOR_LENGTH,
            REGISTERS_OFFSET + SENSOR_LENGTH * 2,
            REGISTERS_OFFSET + SENSOR_LENGTH * 3,
            REGISTERS_OFFSET + SENSOR_LENGTH * 6,
            REGISTERS_OFFSET + SENSOR_LENGTH * 7,
            REGISTERS_OFFSET + SENSOR_LENGTH * 8
    };
    private static final int ADDRESS_OFFSET = REGISTERS_OFFSET;
    private static final int BOUDRATE_OFFSET = REGISTERS_OFFSET + 2;
    private static final int ALARM1_OFFSET = REGISTERS_OFFSET + 4;
    private static final int ALARM2_OFFSET = REGISTERS_OFFSET + 6;
    private static final int ALARM3_OFFSET = REGISTERS_OFFSET + 8;
    private static final int MUTESTATE_OFFSET = REGISTERS_OFFSET + 10;
    private static final int VOLUME_OFFSET = REGISTERS_OFFSET + 12;

    private static final int ALARM4_OFFSET = REGISTERS_OFFSET + 104;
    private static final int ALARM5_OFFSET = REGISTERS_OFFSET + 106;
    private static final int ALARM6_OFFSET = REGISTERS_OFFSET + 108;

    private static final int ZERO_OFFSET = REGISTERS_OFFSET + 110;
    private static final int FULL_OFFSET = REGISTERS_OFFSET + 114;


    static final int FACTORYCHAR_OFFSET = 0;
    static final int GASINDEX_OFFSET = 2;
    static final int PRESSUREMAX_OFFSET = 4;
    static final int PRESSUREMIN_OFFSET = 8;
    static final int DISPLAYVAL_OFFSET = 12;
    static final int STATE_OFFSET = 16;
    static final int MEASURERANGEINDEX_OFFSET = 18;

    private byte[] registers = new byte[BUFFERLENGTH];
    private int sensorAmount = 6;

    public int getRegisterLength() {
        return registerLength;
    }

    final private int registerLength = 90;

    DeviceEntity() {

    }

    DeviceEntity(byte[] data, int length) {
        setRegisters(data, length);
    }

    DeviceEntity(DeviceEntity deviceEntity) {
        this.registers = deviceEntity.registers.clone();
        this.sensorAmount = deviceEntity.sensorAmount;
    }

    byte[] getRegisters() {
        return registers;
    }

    /**
     * 更新寄存器
     *
     * @param data 一组数据
     * @throws ArrayIndexOutOfBoundsException buffer或data不够长
     */
    int setRegisters(byte[] data, int length) throws ArrayIndexOutOfBoundsException {
        if (data.length < BUFFERLENGTH) {
            throw new ArrayIndexOutOfBoundsException();
        }
        this.sensorAmount = 6;
        int whichframe = whichFrame(data);
        System.arraycopy(data, 3, registers, 3 + 100 * whichframe, 100);
        if (whichframe == 0) {
            registers[2] = data[2];
        } else {
            registers[2] += data[2];
        }
        return whichframe;
    }

    static int whichFrame(byte[] data) {
        int reg2 = (data[5] & 0xff) << 8;
        reg2 |= (data[6] & 0xff);
        Log.d("", "whichFrame: 波特率" + reg2);
        if (reg2 > 100) {
            return 0;
        } else {
            return 1;
        }
    }

    private int evalSensorAmount(int length) {
        length += REGISTERS_OFFSET;
        for (int i = SENSORS_OFFSET.length - 1; i >= 0; i--) {
            if (length >= SENSORS_OFFSET[i]) {
                return i + 1;
            }
        }
        return 0;
    }

    int getChannelAmount() {
        return this.sensorAmount;
    }

    /**
     * 获得传感器数据
     *
     * @return 传感器List
     */
    List<Sensor> getSensors() {
        List<Sensor> sensorList = new ArrayList<>();
        for (int i = 0; i < this.sensorAmount; i++) {
            sensorList.add(new Sensor(registers, SENSORS_OFFSET[i]));
        }
        return sensorList;
    }

    /**
     * 写入一个16int位值
     *
     * @param value 写入值
     * @param index byte索引
     */
    private void set16register(int value, int index) {
        registers[index] = (byte) (value >> 8);
        registers[index + 1] = (byte) value;
    }

    /**
     * 读一个16int位值
     *
     * @param index byte索引
     * @return 索引处int值
     */
    private int get16register(int index) {
        int val = 0;
        val |= (registers[index] & 0xff) << 8;
        val |= registers[index + 1] & 0xff;
        return val;
    }

    /**
     * 写入一个32位float值
     *
     * @param value 写入值
     * @param index byte索引
     */
    private void set32floatRegister(float value, int index) {
        int intValue = Float.floatToIntBits(value);
        set32intRegister(intValue, index);
    }

    /**
     * 读一个32位float值
     *
     * @param index byte索引
     * @return 索引处float值
     */
    private float get32floatRegister(int index) {
        int intValue;
        intValue = get32intRegister(index);
        return Float.intBitsToFloat(intValue);
    }

    /**
     * 读一个32位int值
     *
     * @param index byte索引值
     * @return 索引处int值
     */
    private int get32intRegister(int index) {
        int intValue = 0;
        intValue |= (registers[index] & 0xff) << 24;
        intValue |= (registers[index + 1] & 0xff) << 16;
        intValue |= (registers[index + 2] & 0xff) << 8;
        intValue |= registers[index + 3] & 0xff;
        return intValue;
    }

    /**
     * 设一个32位int值
     *
     * @param value 值
     * @param index 索引值
     */
    private void set32intRegister(int value, int index) {
        registers[index] = (byte) ((value >> 24) & 0xff);
        registers[index + 1] = (byte) ((value >> 16) & 0xff);
        registers[index + 2] = (byte) ((value >> 8) & 0xff);
        registers[index + 3] = (byte) (value & 0xff);
    }


    /**
     * 获得气体种类
     *
     * @param sensorIndex sensor索引
     * @return 气体种类
     */
    int getGasClass(int sensorIndex) {
        return get16register(SENSORS_OFFSET[sensorIndex] + GASINDEX_OFFSET);
    }

    /**
     * 设置气体种类
     *
     * @param sensorIndex sensor索引
     * @param gasIndex    气体索引
     */
    void setGasClass(int sensorIndex, int gasIndex) {
        set16register(gasIndex, SENSORS_OFFSET[sensorIndex] + GASINDEX_OFFSET);
    }

    /**
     * 获得上限
     *
     * @param sensorIndex sensor索引
     * @return 上限
     */
    float getMax(int sensorIndex) {
        return get32floatRegister(SENSORS_OFFSET[sensorIndex] + PRESSUREMAX_OFFSET);
    }

    /**
     * 设置上限
     *
     * @param sensorIndex sensor索引
     * @param max         上限值
     */
    void setMax(int sensorIndex, float max) {
        set32floatRegister(max, SENSORS_OFFSET[sensorIndex] + PRESSUREMAX_OFFSET);
    }

    /**
     * 获得下限
     *
     * @param sensorIndex sensor索引
     * @return 下限
     */
    float getMin(int sensorIndex) {
        return get32floatRegister(SENSORS_OFFSET[sensorIndex] + PRESSUREMIN_OFFSET);
    }

    /**
     * 设置下限
     *
     * @param sensorIndex sensor索引
     * @param min         上限
     */
    void setMin(int sensorIndex, float min) {
        set32floatRegister(min, SENSORS_OFFSET[sensorIndex] + PRESSUREMIN_OFFSET);
    }

    int getMeasureRangeIndex(int sensorIndex) {
        return get16register(SENSORS_OFFSET[sensorIndex] + MEASURERANGEINDEX_OFFSET);
    }

    void setMeasureRangeIndex(int sensorIndex, int value) {
        set16register(value, SENSORS_OFFSET[sensorIndex] + MEASURERANGEINDEX_OFFSET);
    }

    /**
     * 读取地址
     *
     * @return 地址
     */
    int getAddress() {
        return get16register(ADDRESS_OFFSET);
    }

    /**
     * 设置地址
     *
     * @param address 地址
     */
    void setAddress(int address) {
        set16register(address, ADDRESS_OFFSET);
    }

    /**
     * 获得波特率
     *
     * @return 波特率
     */
    int getBoudrate() {
        return get16register(BOUDRATE_OFFSET);
    }

    /**
     * 设置波特率
     *
     * @param boudrate 波特率
     */
    void setBoudrate(int boudrate) {
        set16register(boudrate, BOUDRATE_OFFSET);
    }

    /**
     * 获得音量
     *
     * @return 音量
     */
    int getVolume() {
        return get16register(VOLUME_OFFSET);
    }

    /**
     * 设置音量
     *
     * @param volume 音量
     */
    void setVolume(int volume) {
        set16register(volume, VOLUME_OFFSET);
    }

    /**
     * 获得满点
     *
     * @return 满点
     */
    float getFullPointCompensation() {
        return get32floatRegister(FULL_OFFSET);
    }

    /**
     * 设置满点
     *
     * @param compensation 满点
     */
    void setFullPointCompensation(float compensation) {
        set32floatRegister(compensation, FULL_OFFSET);
    }

    /**
     * 获得零点
     *
     * @return 零点
     */
    float getZeroPointCompensation() {
        return get32floatRegister(ZERO_OFFSET);
    }

    /**
     * 设置零点
     *
     * @param compensation 零点
     */
    void setZeroPointCompensation(float compensation) {
        set32floatRegister(compensation, ZERO_OFFSET);
    }

    /**
     * 返回静音状态
     *
     * @return true静音 false不静音
     * @throws Exception 寄存器值错误
     */
    boolean getMutestate() throws Exception {
        int state = get16register(MUTESTATE_OFFSET);
        if (state == 0) {
            return false;
        } else if (state == 1) {
            return true;
        }

        throw new Exception("静音状态错误");
    }

    void setMutestate(int state) {
        set16register(state, MUTESTATE_OFFSET);
    }

    public Boolean allNotused() {
        for (int i = 0; i < this.sensorAmount; i++) {
            if (21 != this.getGasClass(i)) {
                return false;
            }
        }
        return true;
    }
}
